package com.xhtt.modules.inspection.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xhtt.common.utils.Constant;
import com.xhtt.common.utils.DateUtils;
import com.xhtt.common.utils.DoubleInfo;
import com.xhtt.modules.inspection.dao.InsClassesTeamDetailMapper;
import com.xhtt.modules.inspection.entity.InsClassesTeamDetail;
import com.xhtt.modules.inspection.entity.InsTask;
import com.xhtt.modules.inspection.entity.InsTaskStep;
import com.xhtt.modules.inspection.enums.InsPushEnum;
import com.xhtt.modules.inspection.enums.InspectTypeEnum;
import com.xhtt.modules.inspection.enums.ShiftTypeEnum;
import com.xhtt.modules.inspection.service.IInsClassesTeamDetailService;
import com.xhtt.modules.inspection.service.IInsTaskService;
import com.xhtt.modules.inspection.service.IInsTaskStepService;
import com.xhtt.modules.sys.entity.SysUserEntity;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 巡检-排班管理-班组
 * </p>
 *
 * @author xj
 * @since 2019-01-29
 */
@Service
public class InsClassesTeamDetailServiceImpl extends ServiceImpl<InsClassesTeamDetailMapper, InsClassesTeamDetail> implements IInsClassesTeamDetailService {

    @Autowired
    private IInsTaskService insTaskService;

    @Autowired
    private IInsTaskStepService insTaskStepService;

    @Override
    public InsClassesTeamDetail getByTaskDate(LocalDateTime taskDate) {

        return baseMapper
                .selectOne(new LambdaQueryWrapper<InsClassesTeamDetail>()
                        .eq(InsClassesTeamDetail::getDate, taskDate));
    }

    @Override
    public InsClassesTeamDetail getByNow() {
        return getByTaskDate(DateUtils.now());
    }

    @Override
    public List<String> getCurrentUserClasses(SysUserEntity user, Integer taskId) {

        if (user.getUserId().intValue() == Constant.SUPER_ADMIN) {
            return Collections.singletonList("super_admin");
        }

        DateTimeFormatter df = DateTimeFormatter.ofPattern(DateUtils.DATE_PATTERN);
        List<String> result = new ArrayList<>();

        List<DoubleInfo<String, String>> insClassesTeamDetails = baseMapper.getClassesByTeamId(user.getTeamId());
        for (DoubleInfo<String, String> dateList : insClassesTeamDetails) {

            List<LocalDateTime> localDateTimes = DateUtils.getDays(dateList.getFirst(), dateList.getSecond(), DateUtils.DATE_PATTERN);
            for (LocalDateTime localDateTime : localDateTimes) {
                if (localDateTime.isAfter(DateUtils.now().plusDays(-1))) {
                    result.add(df.format(localDateTime));
                }
            }
        }

        if (taskId != null) {
            // 如果已经推送了,日巡检不能修改当天的日期,周巡检不能修改当前周的日期,月巡检不能修改当前月的日期
            List<String> allDates = new ArrayList<>();
            InsTask insTask = insTaskService.getById(taskId);
            if (insTask != null) {
                Integer inspectType = insTask.getInspectType();
                List<InsTaskStep> insTaskSteps = insTaskStepService
                        .list(new LambdaQueryWrapper<InsTaskStep>()
                                .eq(InsTaskStep::getTaskId, taskId)
                                .eq(InsTaskStep::getPushed, InsPushEnum.Y.getCode()));

                // 去重
                List<InsTaskStep> distinctTaskStep = insTaskSteps.stream()
                        .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getTaskStartDate() + ";" + o.getTaskEndDate()))), ArrayList::new));

                if (CollectionUtils.isNotEmpty(distinctTaskStep)) {
                    if (inspectType.equals(InspectTypeEnum.DAY.getCode())) {
                        List<String> startDates = distinctTaskStep.stream().map(insTaskStep -> df.format(insTaskStep.getTaskStartDate())).collect(Collectors.toList());
                        // 取差集
                        result = result.stream().filter(r -> !startDates.contains(r)).collect(Collectors.toList());
                    } else if (inspectType.equals(InspectTypeEnum.WEEK.getCode()) || inspectType.equals(InspectTypeEnum.MONTH.getCode())) { // 周巡检和月巡检相同
                        distinctTaskStep.forEach(insTaskStep -> {
                            List<LocalDateTime> allDate = DateUtils.getDays(df.format(insTaskStep.getTaskStartDate()), df.format(insTaskStep.getTaskEndDate()), DateUtils.DATE_PATTERN);
                            List<String> allDateStr = allDate.stream().map(df::format).collect(Collectors.toList());
                            allDates.addAll(allDateStr);
                        });
                        result = result.stream().filter(r -> !allDates.contains(r)).collect(Collectors.toList());
                    }
                }
            }
        }

        return result;
    }

    @Override
    public int getShiftTypeByDate(LocalDateTime dateTime, Integer teamId) {

        InsClassesTeamDetail insClassesTeamDetail = baseMapper
                .selectOne(new LambdaQueryWrapper<InsClassesTeamDetail>()
                        .eq(InsClassesTeamDetail::getDate, DateUtils.df.format(dateTime)));
        if (insClassesTeamDetail != null) {
            if (insClassesTeamDetail.getTeamMorning().equals(teamId)) {
                return ShiftTypeEnum.DAY.getCode();
            } else if (insClassesTeamDetail.getTeamNight().equals(teamId)) {
                return ShiftTypeEnum.NIGHT.getCode();
            } else {
                return ShiftTypeEnum.NO.getCode();
            }
        }
        return 0;
    }

    @Override
    public List<LocalDateTime> getDatesByTeamId(Integer teamId) {

        return baseMapper.getDatesByTeamId(teamId);
    }

    @Override
    public List<InsClassesTeamDetail> queryClassesByMonth(String month) {
        return baseMapper.queryClassesByMonth(month);
    }

    @Override
    public int getShiftTypeByDate(String date, Integer teamId) {
        return baseMapper.getShiftType(teamId, date);
    }

    @Override
    public InsClassesTeamDetail getAgoByTaskId(Integer taskId) {
        return baseMapper.getAgoByTaskId(taskId);
    }
}
